/**
 * Copyright (C) 2009 IcyRiver / Wesley He
 *
 * IcyRiver Lib  may be copied only under the terms of the GNU General
 * Public License V1, which may be found in the IcyRiver.net source kit.
 * Please visit the IcyRiver Home Page http://icyriver.net/ for more detail.
 **/

//thread.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include <stdlib.h>
#include <pthread.h>

#include "thread.h"

//int g_thread_init_pthread_lock(pthread_mutex_t *pthread_lock)
/*}}}*/
/*
   {
   pthread_mutexattr_t mat;
   int result;

   if ((result=pthread_mutexattr_init(&mat)) != 0)
   {
#ifdef __DEBUG__
fprintf(stderr,"file: %s, line: %d:g_pthread_init_pthread_lock() call pthread_mutexattr_init fail: %s.\n",\
__FILE__, __LINE__, strerror(errno));
#endif
return result;
}
if ((result=pthread_mutexattr_settype(&mat, \
PTHREAD_MUTEX_ERRORCHECK)) != 0)
{
#ifdef __DEBUG__
fprintf(stderr,"file: %s, line: %d:g_pthread_init_pthread_lock() call pthread_mutexattr_settype fail: %s.\n",\
__FILE__, __LINE__, strerror(errno));
#endif
return result;
}
if ((result=pthread_mutex_init(pthread_lock, &mat)) != 0)
{
#ifdef __DEBUG__
fprintf(stderr,"file: %s, line: %d:g_pthread_init_pthread_lock() call pthread_mutex_init fail: %s.\n",\
__FILE__, __LINE__, strerror(errno));
#endif
return result;
}
if ((result=pthread_mutexattr_destroy(&mat)) != 0)
{
#ifdef __DEBUG__
fprintf(stderr,"file: %s, line: %d:g_pthread_init_pthread_lock() call pthread_mutexattr_destroy fail: %s.\n",\
__FILE__, __LINE__, strerror(errno));
#endif
return result;
}

return 0;
}*/
/*}}}*/

int g_thread_init_pthread_attr(pthread_attr_t *pattr)
	/*{{{*/
{
	size_t stack_size;
	int result;

	if ((result=pthread_attr_init(pattr)) != 0)
	{
#ifdef __DEBUG__
		fprintf(stderr,"file: %s, line: %d:g_thread_init_pthread_attr() call pthread_attr_init failed: %s.\n",\
				__FILE__, __LINE__, strerror(errno));
#endif
		return result;
	}

	if ((result=pthread_attr_setdetachstate(pattr, \
					PTHREAD_CREATE_DETACHED)) != 0)
	{
#ifdef __DEBUG__
		fprintf(stderr,"file: %s, line: %d:g_thread_init_pthread_attr() call pthread_attr_setdetachstate failed: %s.\n",\
				__FILE__, __LINE__, strerror(errno));
#endif
		return result;
	}

#ifdef _POSIX_THREAD_ATTR_STACKSIZE
	if ((result=pthread_attr_getstacksize(pattr, &stack_size)) != 0)
	{
#ifdef __DEBUG__
		fprintf(stderr,"file: %s, line: %d:g_thread_init_pthread_attr() call pthread_attr_getstacksize failed: %s.\n",\
				__FILE__, __LINE__, strerror(errno));
#endif
		return result;
	}

	if (stack_size < 2 * 1024 * 1024)
	{
		if ((result=pthread_attr_setstacksize(pattr, 2*1024*1024)) != 0)
		{
#ifdef __DEBUG__
			fprintf(stderr,"file: %s, line: %d:g_thread_init_pthread_attr() call pthread_attr_setstacksize failed: %s.\n",__FILE__, __LINE__, strerror(errno));
#endif
			return result;
		}
	}
#endif

	return 0;
}
/*}}}*/

int g_thread_create_work_threads(int *count, void *(*start_func)(void *), \
		void *arg, pthread_t *tids)
/*{{{*/
{
	int result;
	pthread_attr_t thread_attr;

	if((result=g_thread_init_pthread_attr(&thread_attr))!=0)
	{
		return result;
	}

	result = 0;
	if ((result = pthread_create(tids, &thread_attr, \
					g_thread_entrance, arg)) != 0)
	{
#ifdef __DEBUG__
		fprintf(stderr,"file: %s, line: %d:g_thread_create_work_threads call pthread_create failed: %s.\n",\
				__FILE__, __LINE__, strerror(errno));
		pthread_attr_destroy(&thread_attr);
		return result;
#endif
	}
#ifdef __DEBUG__
		fprintf(stderr,"file: %s, line: %d:g_thread_create_work_threads call pthread_create result is  %d \n",\
				__FILE__, __LINE__, result);
#endif

	pthread_attr_destroy(&thread_attr);
	return result;
}
/*}}}*/


void* g_thread_entrance(void* arg)
/*{{{*/
{
#ifdef __DEBUG__
		fprintf(stderr,"file: %s, line: %d:thread is working now\n",\
				__FILE__, __LINE__);
#endif
	pthread_exit("exit\n");
	return 0;
}
/*}}}*/
